package ananly;


import oracle.xml.parser.v2.SAXParser;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;

import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

/*XML文件解析类    我用的是ORACLE的解析包xmlparserv2.jar
* SAX在解析的过程中，在一个元素结尾与另一个元素开始处，解析器会把他当成一个文本结点。 
* characters方法会多出很多空格，最后用一个笨的方法解决了他，还请批评指正。 
*/
public class SourceProcessor extends Thread implements ContentHandler {

    private List<List<String>> cacheList = new ArrayList<List<String>>();
    private SaxProcessor saxProcessor;
    private String targetFilename = null;
    private boolean recordStart = false;
    private boolean useable = false;

    private List<String> curDatas = new ArrayList<String>();
    private StringBuffer curData = new StringBuffer();

    public boolean isRecordStart() {
        return recordStart;
    }

    public void setRecordStart(boolean recordStart) {
        this.recordStart = recordStart;
    }

    public SourceProcessor(String threadName) {
        super(threadName);
    }

    public String getTargetFilename() {
        return targetFilename;
    }

    public void setTargetFilename(String targetFilename) {
        this.targetFilename = targetFilename;
    }

    public void characters(char[] ch, int start, int length)
            throws SAXException {

        if (this.useable == true) {
            curData.append(new String(ch, start, length));
        }
    }

    public void endDocument() throws SAXException {
        if (cacheList.size() > 0) {
            this.saxProcessor.addToQueue(cacheList);
        }
        this.saxProcessor.setParsingComplete();
        System.out.println("over");
    }

    public void endElement(String uri, String localName, String name)
            throws SAXException {
    /* 一条记录完成 */
        if (localName.equals(this.saxProcessor.getSetting("group", "group"))) {
            cacheList.add(curDatas);
            this.curDatas = new ArrayList<String>();

            if (cacheList.size() >= 100) {
                this.saxProcessor.addToQueue(cacheList);
                cacheList = new ArrayList<List<String>>();
            }
        } else if (this.recordStart == true) {
            curDatas.add(curData.toString().trim());
            curData = new StringBuffer();
            this.useable = false;
        }
    }

    public void endPrefixMapping(String prefix) throws SAXException {

    }

    public void ignorableWhitespace(char[] ch, int start, int length)
            throws SAXException {
    }

    public void processingInstruction(String target, String data)
            throws SAXException {

    }

    public void setDocumentLocator(Locator locator) {

    }

    public void skippedEntity(String name) throws SAXException {
        // TODO Auto-generated method stub
    }

    public void startDocument() throws SAXException {

    }

    public void startElement(String uri, String localName, String name,
                             Attributes atts) throws SAXException {
        if (localName.equals(this.saxProcessor.getSetting("group", "group"))) {
            this.recordStart = true;
        } else if (recordStart == true) {
      /* 可以收集 */
            this.useable = true;
        }

    }

    public void startPrefixMapping(String prefix, String uri)
            throws SAXException {

    }

    public SaxProcessor getSaxProcessor() {
        return saxProcessor;
    }

    public void setSaxProcessor(SaxProcessor saxProcessor) {
        this.saxProcessor = saxProcessor;
    }

    public void run() {
        try {
            SAXParser parser = new SAXParser();
            parser.setAttribute(SAXParser.STANDALONE, Boolean.valueOf(true));
            parser.setValidationMode(SAXParser.NONVALIDATING);
            parser.setContentHandler(this);
            this.saxProcessor.setParserActive();
            parser.parse(new FileInputStream(this.targetFilename));

        } catch (ProcessingCompleteException pce) {
            pce.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public boolean isUseable() {
        return useable;
    }

    public void setUseable(boolean useable) {
        this.useable = useable;
    }

}